﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using Infinity.Expressions.Core;

namespace Infinity.Expressions.Loops
{
	/// <summary>
	/// A for ciklus reprezentációja
	/// </summary>
	public class ForLoop : Loop
	{
		public int By { get; set; }
		public int End { get; set; }
		public int Start { get; set; }

		public int Index { get; set; }

		public Variable LoopVariable { get; set; }

		public ForLoop()
		{
			Index = Start = End = 0;
			By = 1;
			LoopVariable = new Variable() { Type = typeof(int), Name = "loopIndex", Value = Start };
		}

		public override void Run()
		{
			Index = Start;
			base.Run();
		}

		public override bool Step()
		{
			bool ret = Index != End;
			Index += By;
			return ret;
		}

		protected override Expression BodyExpression
		{
			get
			{
				LoopVariable.Value = Start;
				LabelTarget breakLabel = Expression.Label("break");
				var indexVariable = LoopVariable.ToExpression();
				var block = Expression.Block(
					new[] { indexVariable },
					Expression.Assign(indexVariable, Expression.Constant(Start)),
					Expression.Loop(
						Expression.IfThenElse(
							Expression.NotEqual(indexVariable, Expression.Constant(End)),
							Expression.Block(
								Body.ToExpression(),
								Expression.AddAssign(indexVariable, Expression.Constant(By))
							),
							Expression.Break(breakLabel)
						),
						breakLabel
					)
				);
				return block;
			}
		}
	}
}
